import matplotlib
#~ matplotlib.use('Agg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
import pylab as p
import time

import vtk
import wx
from vtk.wx.wxVTKRenderWindowInteractor import *


class Scatter(wx.Frame):
    def __init__(self, parent, data1, data2, stanceID1, stanceID2):
        self.windowsize = [648, 512]
        self.xyValues1 = data1[0]
        self.xLabel1 = data1[1]
        self.yLabel1 = data1[2]
        self.xyValues2 = data2[0]
        self.xLabel2 = data2[1]
        self.yLabel2 = data2[2]
        self.stanceID1 = stanceID1
        self.stanceID2 = stanceID2
        self.plotcolor1 = (0.0, 0.0, 1.0)
        self.plotcolor2 = (1.0, 1.0, 0.0)
        self.parent = parent
        
        wx.Frame.__init__(self, None, -1, pos = wx.Point(100, 100),\
                                        size = self.windowsize, style=wx.DEFAULT_FRAME_STYLE, title=u'Scatter Plot')
        self.Bind(wx.EVT_CLOSE, self.OnQuit)
        #~ self.Bind(wx.EVT_SIZE, self.OnResize)
        #~ self.canvas.Bind(wx.EVT_KEY_DOWN, self.onKeyEvent)
        self.SetupRenderWindow()
        

        self.ShowPlot()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.iren, 1)
        self.SetSizer(sizer)                  
        self.Show(True)

        self.Fit()
        #~ self.Build_Menus()     


    def OnResize(self, event):
        print self.GetSize()
    
    def SetupRenderWindow(self):
        self.iren = wxVTKRenderWindowInteractor(self, -1)
        self.iren.SetSize([self.windowsize[0], self.windowsize[1]])
        self.renWin = self.iren.GetRenderWindow()        
        self.ren = vtk.vtkRenderer()
        self.renWin.AddRenderer(self.ren)
        
        self.iren.Unbind(wx.EVT_LEFT_DOWN)
        #~ self.iren.Bind(wx.EVT_LEFT_DOWN, self.PlotSelected)
        self.iren.Unbind(wx.EVT_RIGHT_DOWN)        
        #~ self.iren.Bind(wx.EVT_RIGHT_DOWN, self.ShowMenu)
        
        
    def DefineLookupTable(self):
        whitening = 0.7
        self.dynamic_generic = vtk.vtkLookupTable()
        self.dynamic_generic.SetNumberOfColors(4)
        self.dynamic_generic.SetRange(0, 4)
        self.dynamic_generic.SetTableValue( 0, (whitening, whitening, whitening ,0.0)) 
        self.dynamic_generic.SetTableValue( 1, (0.0, 0.0, 0.0 ,0.7)) 
        self.dynamic_generic.SetTableValue( 2, (1.0, 1.0, 1.0 ,1.0)) 
        self.dynamic_generic.SetTableValue( 3, (whitening, whitening, whitening ,1.0)) 
        self.dynamic_generic.Build()

    #~ def ShowOverlay(self):
        #~ try:
            #~ self.ren.RemoveActor(self.selectionActor)
        #~ except AttributeError:
            #~ pass
        #~ self.canvas = vtk.vtkImageCanvasSource2D()
        #~ self.canvas.SetNumberOfScalarComponents(4)
        #~ self.canvas.SetScalarTypeToUnsignedChar()
        #~ self.canvas.SetExtent(0, self.windowsize[0]-1, 0, self.windowsize[1]-1, 0, 0)        
        #~ self.canvas.SetDrawColor(0,0,0)
        #~ self.canvas.FillBox(0, self.windowsize[0], 0, 50)        
        #~ self.canvas.SetDrawColor(1,0,0)

        #~ if self.whichdata == 0:
            #~ sortedlist = self.parent.parent.splineCollection_seqfilter[:]
        #~ elif self.whichdata == 1:
            #~ sortedlist = self.parent.parent.splineReferences_seqfilter[:]
        #~ sortedlist.sort()
        #~ for i in range(0, len(sortedlist)/2):
            #~ self.canvas.FillBox(sortedlist[i*2], sortedlist[i*2+1], 0, 50)
        
        #~ self.canvas.SetDrawColor(2,0,0)
        #~ if self.cursor > -1:            
            #~ self.canvas.FillBox(self.cursor, self.cursor+1, 0, 50)
        
        #~ imagemaptocolors = vtk.vtkImageMapToColors()
        #~ imagemaptocolors.SetOutputFormatToRGBA ()
        #~ imagemaptocolors.SetLookupTable(self.dynamic_generic)
        #~ imagemaptocolors.SetInput(self.canvas.GetOutput())
        
        #~ bbmap = vtk.vtkImageMapper()
        #~ bbmap.SetColorWindow(255.5)
        #~ bbmap.SetColorLevel(127.5)
        #~ bbmap.SetInput(imagemaptocolors.GetOutput())
        #~ self.selectionActor = vtk.vtkActor2D()
        #~ self.selectionActor.SetMapper(bbmap)
        #~ self.ren.AddActor(self.selectionActor)
        #~ self.renWin.Render()
        
    #~ def PlotSelected(self, event):
        #~ try:
            #~ self.iren.RemoveObserver(self.lbpf)
            #~ self.iren.RemoveObserver(self.lbpg)
        #~ except AttributeError:
            #~ pass
        #~ x, y = self.iren.GetEventPosition()
        
        #~ index =0
        #~ if self.whichdata == 0:
            #~ index = int(float(x)/float(self.windowsize[0]) * \
                                                    #~ len(self.parent.parent.splineCollection))
            #~ act = self.parent.parent.ShowPose(self.parent.parent.splineCollection[index]['blPos'], type = 2)
            #~ self.parent.SetSliders(self.parent.parent.splineCollection[index]['stance'])                        
        #~ else:
            #~ index = int(float(x)/float(self.windowsize[0]) * \
                                                    #~ len(self.parent.parent.splineReferences))
            #~ act = self.parent.parent.ShowPose(self.parent.parent.splineReferences[index]['blPos'], type = 2)
            #~ self.parent.SetSliders(self.parent.parent.splineReferences[index]['stance'])
        #~ self.parent.tracer.ClearTraces(self.whichdata)
        #~ self.parent.tracer.DrawTrace(self.whichdata, index, None)
                                                    
        #~ self.clicktime = time.clock()
        #~ if self.clicktime - self.lastclicktime < 1:
            #~ if self.whichdata == 0:
                #~ sortedlist = self.parent.parent.splineCollection_seqfilter[:]
            #~ else:
                #~ sortedlist = self.parent.parent.splineReferences_seqfilter[:]
            #~ sortedlist.sort()
            #~ for i in range(0, len(sortedlist)):
                #~ try:
                    #~ if x >= sortedlist[i] and\
                        #~ x <= sortedlist[i + 1]:
                        #~ sortedlist.pop(i+1)
                        #~ sortedlist.pop(i)
                        #~ if self.whichdata == 0:
                            #~ self.parent.parent.splineCollection_seqfilter = sortedlist
                        #~ elif self.whichdata == 1:
                            #~ self.parent.parent.splineReferences_seqfilter = sortedlist
                        #~ break
                #~ except IndexError:
                    #~ pass
            #~ self.parent.UpdateSequencePlotOverlays()
            #~ self.UpdateFilters()
        #~ else:
            #~ if self.whichdata == 0:
                #~ if self.parent.parent.splineCollection_seqfilter == []:
                    #~ self.parent.parent.splineCollection_seqfilter.append(0)
                    #~ self.parent.parent.splineCollection_seqfilter.append(x)
                    #~ self.parent.parent.splineCollection_seqfilter.append(x)
                    #~ self.parent.parent.splineCollection_seqfilter.append(self.windowsize[0])
                #~ else:
                    #~ self.parent.parent.splineCollection_seqfilter.append(x)
                    #~ self.parent.parent.splineCollection_seqfilter.append(x)
            #~ elif self.whichdata == 1:
                #~ if self.parent.parent.splineReferences_seqfilter == []:
                    #~ self.parent.parent.splineReferences_seqfilter.append(0)
                    #~ self.parent.parent.splineReferences_seqfilter.append(x)
                    #~ self.parent.parent.splineReferences_seqfilter.append(x)
                    #~ self.parent.parent.splineReferences_seqfilter.append(self.windowsize[0])
                #~ else:
                    #~ self.parent.parent.splineReferences_seqfilter.append(x)
                    #~ self.parent.parent.splineReferences_seqfilter.append(x)
            
            #~ self.lbpf = self.iren.AddObserver("MouseMoveEvent", \
                                                                                #~ self.PlotMove, 2.0)
            #~ self.lbpg = self.iren.AddObserver("LeftButtonReleaseEvent", \
                                                                                #~ self.PlotRelease, 2.0)
            #~ self.parent.editorpanel.button_4.SetValue(True)
            #~ self.parent.OnChangeFilters(None)
        #~ self.lastclicktime = self.clicktime
        
    #~ def PlotMove(self, event, bla):
        #~ x, y = self.iren.GetEventPosition()
        #~ if self.whichdata == 0:
            #~ if len(self.parent.parent.splineCollection_seqfilter)==4:
                #~ self.parent.parent.splineCollection_seqfilter.pop(2)
                #~ self.parent.parent.splineCollection_seqfilter.insert(2, x)
            #~ else:
                #~ self.parent.parent.splineCollection_seqfilter.pop(len(self.parent.parent.splineCollection_seqfilter)-1)
                #~ self.parent.parent.splineCollection_seqfilter.append(x)
        #~ elif self.whichdata == 1:
            #~ if len(self.parent.parent.splineReferences_seqfilter)==4:
                #~ self.parent.parent.splineReferences_seqfilter.pop(2)
                #~ self.parent.parent.splineReferences_seqfilter.insert(2, x)
            #~ else:
                #~ self.parent.parent.splineReferences_seqfilter.pop(len(self.parent.parent.splineReferences_seqfilter)-1)
                #~ self.parent.parent.splineReferences_seqfilter.append(x)
        #~ self.parent.UpdateSequencePlotOverlays()
        
    #~ def PlotRelease(self, event, bla):
        #~ self.iren.RemoveObserver(self.lbpf)
        #~ self.iren.RemoveObserver(self.lbpg)
        #~ if self.whichdata == 0:
            #~ if self.parent.parent.splineCollection_seqfilter[len(self.parent.parent.splineCollection_seqfilter)-1] == self.parent.parent.splineCollection_seqfilter[len(self.parent.parent.splineCollection_seqfilter)-2]:
                #~ self.parent.parent.splineCollection_seqfilter.pop(len(self.parent.parent.splineCollection_seqfilter)-1)
                #~ self.parent.parent.splineCollection_seqfilter.pop(len(self.parent.parent.splineCollection_seqfilter)-1)
        #~ elif self.whichdata == 1:
            #~ if self.parent.parent.splineReferences_seqfilter[len(self.parent.parent.splineReferences_seqfilter)-1] == self.parent.parent.splineReferences_seqfilter[len(self.parent.parent.splineReferences_seqfilter)-2]:
                #~ self.parent.parent.splineReferences_seqfilter.pop(len(self.parent.parent.splineReferences_seqfilter)-1)
                #~ self.parent.parent.splineReferences_seqfilter.pop(len(self.parent.parent.splineReferences_seqfilter)-1)
        #~ self.UpdateFilters()
        
            
    #~ def UpdateFilters(self):
        #~ self.filtervalues = []
        #~ if self.whichdata == 0:
            #~ sortedlist = self.parent.parent.splineCollection_seqfilter[:]
        #~ elif self.whichdata == 1:
            #~ sortedlist = self.parent.parent.splineReferences_seqfilter[:]
        #~ sortedlist.sort()
        #~ if self.whichdata == 0:
            #~ for i in range(0, len(sortedlist)):
                #~ self.filtervalues.append(int(float(sortedlist[i])/float(self.windowsize[0]) * \
                                                    #~ len(self.parent.parent.splineCollection)))
            #~ self.parent.parent.Filters.RestartFiltering()
        #~ else:
            #~ for i in range(0, len(sortedlist)):
                #~ self.filtervalues.append(int(float(sortedlist[i])/float(self.windowsize[0]) * \
                                                    #~ len(self.parent.parent.splineReferences)))
            #~ self.parent.parent.Filters.RestartFilteringReferences()
        
    def ShowPlot(self):       
        # The vtkImageImporter will treat a python string as a void pointer
        self.importer = vtk.vtkImageImport()
        self.importer.SetDataScalarTypeToUnsignedChar()
        self.importer.SetNumberOfScalarComponents(4)

        canvasset = self.CreatePlot()
        canvas = canvasset[0]
        w = canvasset[1]
        h = canvasset[2]

        extent = (0, w-1, 0, h-1, 0, 0)
        self.importer.SetWholeExtent(extent)
        self.importer.SetDataExtent(extent)
        self.importer.SetImportVoidPointer(canvas.buffer_rgba(0,0), 1)
        self.importer.Update()
        #~ for i in range(0,256):
            #~ print importer.GetOutput().GetScalarComponentAsFloat (i, i, 0, 0)
            #~ time.sleep(0.1)

        # It's upside-down when loaded, so add a flip filter
        imflip = vtk.vtkImageFlip()
        imflip.SetInput(self.importer.GetOutput())
        imflip.SetFilteredAxis(1)

        self.bbmap = vtk.vtkImageMapper()
        self.bbmap.SetColorWindow(255.5)
        self.bbmap.SetColorLevel(127.5)
        self.bbmap.SetInput(imflip.GetOutput())
        bbact = vtk.vtkActor2D()
        bbact.SetMapper(self.bbmap)
        

        #~ bbact.SetDisplayPosition (int(-0.16*self.windowsize[0]),-6)
        #~ bbact.SetDisplayPosition (-220, -6) ##width = 1348 = -220, #width = 692 = -110
        self.ren.AddActor(bbact)
        self.iren.Render()

    def CreatePlot(self):
        self.fig = Figure()
        self.fig.frameon = True
        self.canvas = FigCanvas(self, -1, self.fig)
        w,h = int(self.windowsize[0]), int(self.windowsize[1])
        dpi = self.canvas.figure.get_dpi()
        self.fig.set_size_inches(1.0*w / dpi, 1.0*h / dpi)        
        
        self.UpdatePlot()
        #~ self.ax = self.fig.add_subplot(111)
        #~ self.ax.set_xlabel(self.xLabel1)
        #~ self.ax.set_ylabel(self.yLabel1)
        #~ rect = self.ax.patch
        #~ rect.set_facecolor((1, 1, 1))
        #~ if self.xyValues1:
            #~ xy1_array = matplotlib.numpy.array(self.xyValues1)        
            #~ columns1 = matplotlib.numpy.column_stack(self.xyValues1).tolist()
            #~ self.ax.plot(columns1[0], columns1[1], 'o',  color=self.plotcolor1)
        #~ if self.xyValues2:
            #~ xy2_array = matplotlib.numpy.array(self.xyValues2)
            #~ columns2 = matplotlib.numpy.column_stack(self.xyValues2).tolist()        
            #~ self.ax.plot(columns2[0], columns2[1], 'o',  color=self.plotcolor2)
        #~ self.canvas.draw() 

        return [self.canvas, w, h]

    def UpdatePlot(self):
        try:
            self.fig.delaxes(self.ax)
        except AttributeError:
            pass
        
        self.ax = self.fig.add_subplot(111)
        self.ax.set_xlabel(self.xLabel1)
        self.ax.set_ylabel(self.yLabel1)        
        rect = self.ax.patch
        rect.set_facecolor((1, 1, 1))
        if self.xyValues1:
            xy1_array = matplotlib.numpy.array(self.xyValues1)        
            columns1 = matplotlib.numpy.column_stack(self.xyValues1).tolist()
            self.ax.plot(columns1[0], columns1[1], 'o',  color=self.plotcolor1)
        if self.xyValues2:
            xy2_array = matplotlib.numpy.array(self.xyValues2)
            columns2 = matplotlib.numpy.column_stack(self.xyValues2).tolist()        
            self.ax.plot(columns2[0], columns2[1], 'o',  color=self.plotcolor2)
        self.ax.set_xbound (-180, 180)
        self.ax.set_ybound (-180, 180)
        self.ax.grid()
        self.canvas.draw()      
        
        try:
            w,h = int(self.windowsize[0]), int(self.windowsize[1])
            extent = (0, w-1, 0, h-1, 0, 0)
            self.importer.SetWholeExtent(extent)
            self.importer.SetDataExtent(extent)
            self.importer.SetImportVoidPointer(self.canvas.buffer_rgba(0,0), 1)
            self.importer.Update()
            self.bbmap.Update()
        except AttributeError:
            pass
        
    def OnQuit(self, event):
        for scatterplot in self.parent.scatterplotlist:
            if scatterplot == self:
                self.parent.scatterplotlist.remove(scatterplot)        
        self.Destroy()
  
class MyApp(wx.App):
    def OnInit(self):
        plotsie = Scatter(None, None)        
        plotsie.Show()
        self.SetTopWindow(frame)
        return 1

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()